package cn.mothin.frame.core.base;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.SessionAware;

import cn.mothin.frame.bean.ActionResult;
import cn.mothin.frame.bean.LoginUser;
import cn.mothin.frame.core.annotation.Module;
import cn.mothin.frame.core.bean.SearchData;
import cn.mothin.frame.core.interfaces.ILoginUser;
import cn.mothin.frame.core.interfaces.vo.IViewObject;
import cn.mothin.frame.help.UniqueCode;
import cn.mothin.frame.util.StringUtil;

import com.google.gson.Gson;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;

@SuppressWarnings({ "serial" })
public class BaseAction extends ActionSupport implements Preparable,
		ModelDriven<Object>, SessionAware {
	public static final String LOGIN_SYSTEM_USER_SESSION_ID = "_loginSystemUserSessionId";
	public static final String LOGIN_RANDOM_KEY_SESSION_NAME = "_sessionRandomKey";
	public static final String ACCESS_MODE = "_accessMode";

	/**
	 * 添加数据成功
	 */
	public static final String ADD_OK = "add_ok";
	/**
	 * 添加数据失败
	 */
	public static final String ADD_FAIL = "add_fail";
	/**
	 * 修改数据成功
	 */
	public static final String UPDATE_OK = "update_ok";
	/**
	 * 修改数据失败
	 */
	public static final String UPDATE_FAIL = "update_fail";
	/**
	 * 删除数据成功
	 */
	public static final String DELETE_OK = "delete_ok";
	/**
	 * 删除数据失败
	 */
	public static final String DELETE_FAIL = "delete_fail";
	/**
	 * 错误
	 */
	public static final String ERROR = "action_error";

	protected final Log log = LogFactory.getLog(getClass());
	/**
	 * 不存在此页面的错误提示
	 */
	public static final String ERR_MESSAGE = "No Such Page";

	private String lastError = null;

	protected Map<String, Object> session;

	public String getLastError() {
		return lastError;
	}

	protected void setLastError(String lastError) {
		this.lastError = lastError;
	}

	public String execute() {
		return "exception_error_url";
	}

	/**
	 * 默认prepare
	 */
	@Override
	public void prepare() {
		Object obj = getModel();
		if (obj != null && obj instanceof IViewObject) {
			IViewObject vo = (IViewObject) obj;
			Map<String, Object> map = ActionContext.getContext()
					.getParameters();
			Map<String, SearchData> search = new HashMap<String, SearchData>();
			Gson gson = new Gson();
			for (String key : map.keySet()) {
				if(!key.startsWith("_search.")){
					continue;
				}
				String keyName=key.substring(8);
				if(keyName.contains(".")){
					continue;
				}
				if(search.containsKey(keyName)){
					continue;
				}
				
				Object data = map.get(key);
				if (data == null||!(data instanceof String[])) {
					continue;
				}
				String s = ((String[]) data)[0];
				if(StringUtil.isNullOrEmpty(s)){
					continue;
				}
				SearchData searchData = gson.fromJson(s, SearchData.class);
				search.put(keyName, searchData);
			}
			if(search.size()>0){
				vo.setSearch(search);
			}
		}
	}

	/**
	 * 默认getModel
	 */
	@Override
	public Object getModel() {
		return null;
	}

	protected String ResultSwitch(String result) {
		if (StringUtil.isNullOrEmpty(result)) {
			return result;
		}

		if (isMobileAccessMode()) {
			return result + ".m";
		}
		return result;
	}

	/**
	 * 获取 HttpServletRequest
	 * 
	 * @return 返回HttpServletRequest
	 */
	public HttpServletRequest getRequest() {
		return ServletActionContext.getRequest();
	}

	/**
	 * 获取 HttpServletResponse
	 * 
	 * @return HttpServletResponse
	 */
	protected HttpServletResponse getResponse() {
		return ServletActionContext.getResponse();
	}

	@Override
	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	public String getSessionId() {
		return getRequest().getSession().getId();
	}

	/**
	 * 数据输出
	 * 
	 * @param text
	 *            字符串
	 * @param contentType
	 *            数据类型
	 * @return
	 */
	protected String render(String text, String contentType) {
		try {
			HttpServletResponse response = ServletActionContext.getResponse();
			response.setContentType(contentType);
			response.getWriter().write(text);
			response.getWriter().flush();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
		return null;
	}

	@SuppressWarnings("deprecation")
	protected String renderAttachment(String name, String type, byte[] bytes) {
		if (name == null || type == null || bytes == null) {
			return null;
		}
		try {
			HttpServletResponse response = ServletActionContext.getResponse();
			response.setHeader("Content-Disposition", "attachment;filename="
					+ URLEncoder.encode(name));
			response.addHeader("Content-Length", String.valueOf(bytes.length));
			response.setContentType(type);
			response.getOutputStream().write(bytes);
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 数据流输出
	 * 
	 * @param bytes
	 *            字节数组
	 * @param contentType
	 *            类型
	 * @return
	 */
	protected String render(byte[] bytes, String contentType) {
		try {
			HttpServletResponse response = ServletActionContext.getResponse();
			response.setContentType(contentType);
			response.getOutputStream().write(bytes);
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 输出字符串数据
	 * 
	 * @param text
	 * @return
	 */
	protected String renderText(String text) {
		return render(text, "text/plain;charset=UTF-8");
	}

	/**
	 * 输出HTML数据
	 * 
	 * @param html
	 * @return
	 */
	protected String renderHtml(String html) {
		return render(html, "text/html;charset=UTF-8");
	}

	/**
	 * 输出XML数据
	 * 
	 * @param xml
	 * @return
	 */
	protected String renderXML(String xml) {
		return render(xml, "text/xml;charset=UTF-8");
	}

	/**
	 * 输出XML数据
	 * 
	 * @param xml
	 * @return
	 */
	protected String renderJson(String data) {
		return render(data, "text/x-json;charset=UTF-8");
	}

	/**
	 * 对象转JSON
	 * 
	 * @param object
	 * @return
	 */
	protected String toJson(Object object) {
		Gson gson = new Gson();
		return gson.toJson(object);
	}

	/**
	 * 转向指定的Action地址
	 * 
	 * @param action
	 * @return
	 * @throws IOException
	 */
	protected String redirectTo(String action, Map<String, String> map) {
		String targetAction = action;
		if (!action.endsWith(".action")) {
			targetAction += ".action";
		}
		try {
			if (map != null && !map.isEmpty()) {
				boolean b = false;
				for (String key : map.keySet()) {
					if (b) {
						targetAction += "&" + key + "=" + map.get(key);
					} else {
						targetAction += "?" + key + "=" + map.get(key);
						b = true;
					}
				}
			}

			getResponse().sendRedirect(targetAction);
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
		return null;
	}

	protected String redirectTo(String action) {
		String targetAction = action;
		if (!action.endsWith(".action")) {
			targetAction += ".action";
		}
		try {
			getResponse().sendRedirect(targetAction);
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
		return null;
	}

	protected void saveLoginUserInfomation(String id, String loginIp,
			boolean superUser) {
		saveLoginUserInfomation(id, loginIp, superUser, null);
	}

	protected void saveLoginUserInfomation(String id, String loginIp,
			boolean superUser, String name) {
		LoginUser loginUser = new LoginUser(id, UniqueCode.make(), loginIp,
				name, superUser);
		saveLoginUserInfomation(loginUser);
	}

	/**
	 * 保存用户登录信息
	 * 
	 * @param loginUserInfomation
	 */
	protected void saveLoginUserInfomation(ILoginUser loginUserInfomation) {
		session.put(LOGIN_SYSTEM_USER_SESSION_ID, loginUserInfomation);
	}

	/**
	 * 获取用户登录信息
	 * 
	 * @return
	 */
	protected ILoginUser getLoginUserInfomation() {
		// 取出Session中的用户信息
		Object obj = session.get(LOGIN_SYSTEM_USER_SESSION_ID);
		if (obj != null && obj instanceof ILoginUser) {
			return (ILoginUser) obj;
		}
		return null;
	}

	protected ILoginUser getLoginUserInfomation(HttpSession httpSession) {
		// 取出Session中的用户信息
		Object obj = httpSession.getAttribute(LOGIN_SYSTEM_USER_SESSION_ID);
		if (obj != null && obj instanceof ILoginUser) {
			return (ILoginUser) obj;
		}
		return null;
	}

	/**
	 * 使Session立即失效
	 */
	protected void clearSession() {
		session.clear();
	}

	/**
	 * 获取访问者IP
	 * 
	 * @return
	 */
	protected String getRemoteAddress() {
		String ip = this.getRequest().getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown"))
			ip = this.getRequest().getHeader("Proxy-Client-IP");
		if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown"))
			ip = this.getRequest().getHeader("WL-Proxy-Client-IP");
		if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown"))
			ip = this.getRequest().getRemoteAddr();
		return ip;
	}

	/**
	 * 获取访问的根路径
	 * 
	 * @return
	 */
	public String getBasePath() {
		String path = getRequest().getContextPath();
		String basePath = getRequest().getScheme()
				+ "://"
				+ getRequest().getServerName()
				+ (getRequest().getServerPort() == 80 ? "" : ":"
						+ getRequest().getServerPort()) + path + "/";
		return basePath;
	}

	protected String saveRandomKeyInSession() {
		String s = UniqueCode.make();
		session.put(LOGIN_RANDOM_KEY_SESSION_NAME, s);
		return s;
	}

	protected String getRandomKeyInSession() {
		Object obj = session.get(LOGIN_RANDOM_KEY_SESSION_NAME);
		if (obj == null) {
			return null;
		}
		return obj.toString();
	}

	protected void clearRandomKeyInSession() {
		session.remove(LOGIN_RANDOM_KEY_SESSION_NAME);
	}

	/**
	 * 
	 * @param bool
	 */
	protected void setMobileAccessMode(boolean bool) {
		session.put(ACCESS_MODE, bool);
	}

	protected boolean isMobileAccessMode() {
		if (session.containsKey(ACCESS_MODE)) {
			return (boolean) session.get(ACCESS_MODE);
		}
		return false;
	}

	/**
	 * 获取当前模块Id
	 * 
	 * @return
	 */
	protected String getModuleId() {
		if (this.getClass().isAnnotationPresent(Module.class)) {
			Module module = this.getClass().getAnnotation(Module.class);
			return module.id();
		}
		return null;
	}

	protected ActionResult createActionResult() {
		return new ActionResult();
	}

	protected ActionResult createActionResult(boolean ok, Object value,
			String message) {
		ActionResult actionResult = new ActionResult();
		actionResult.setMessage(message);
		actionResult.setOk(ok);
		actionResult.setValue(value);
		return actionResult;
	}
}
